use std::collections::HashMap;
use std::ops::Deref;
use std::time::{SystemTime, UNIX_EPOCH};
use uuid::Uuid;
use std::thread;
use crate::log::task_logger::TASK_SUMMARY_LOGGER;
use crate::datafile::taskfile::TaskFileLogger;
use crate::protocol::task::TaskStatus;
use crate::services::manager;
use crate::tasks::task::Task;
use crate::error::ServerError;
use serde::{Serialize, Deserialize};
use tokio;
use once_cell::sync::OnceCell;
use std::sync::Arc;

macro_rules! mgr_init_err {
    () => {
        ServerError::ServiceErrorStr("任务管理器未初始化")
    };
}

macro_rules! get_task_manager {
    () => {
        TASK_MANAGER.get().ok_or_else(|| mgr_init_err!())
    };
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TaskStruct {
    pub workflow_id: Option<u16>,
    pub id: String,
    pub name: String,
    pub service_name: String,
    pub result_addr: String,
    pub status: TaskStatus,
    pub progress_percentage: f64,
    pub error_message: Option<String>,
    pub created_at: u64,
    pub completed_at: Option<u64>
}

pub struct TaskManager {
    pub tasks: HashMap<String, Task>
}

impl TaskManager {
    pub fn new() -> Self {
        TaskManager {
            tasks: HashMap::new(),
        }
    }

    pub fn get_tasks(&self) -> HashMap<String, TaskStruct> {
        let mut tasks = HashMap::new();
        for (id, task) in &self.tasks {
            tasks.insert(id.clone(), TaskStruct {
                workflow_id: task.workflow_id.clone(),
                id: id.clone(),
                name: task.name.clone(),
                service_name: task.service_name.clone(),
                result_addr: task.result_sender_addr.clone(),
                status: task.status.clone(),
                progress_percentage: task.progress_percentage,
                error_message: task.error_message.clone(),
                created_at: task.created_at,
                completed_at: task.completed_at
            });
        }
        tasks
    }

    pub fn add_task(&mut self, task: Task) -> Result<(), ServerError> {
        self.tasks.insert(task.id.clone(), task);
        Ok(())
    }

    pub fn get_task(&self, id: &str) -> Option<&Task> {
        self.tasks.get(id)
    }

    pub fn get_task_mut(&mut self, id: &str) -> Option<&mut Task> {
        self.tasks.get_mut(id)
    }

    pub fn take_task_mut(&mut self, id: &str) -> Option<Task> {
        self.tasks.remove(id)
    }

    pub fn list_tasks(&self) -> Vec<&Task> {
        self.tasks.values().collect()
    }

    pub fn remove_task(&mut self, id: &str) -> Option<Task> {
        self.tasks.remove(id)
    }

    pub fn complete_task(&mut self, id: String, exit_status: TaskStatus) -> Result<(), ServerError> {
        let handle = std::thread::spawn(move || {
            let rt = tokio::runtime::Runtime::new().unwrap();
            let res = rt.block_on(async move {
                let mut manager = get_task_manager!()?.lock().await;
                let task = manager.get_task_mut(&id).unwrap();
                match exit_status {
                    TaskStatus::Completed => {
                        task.set_status(exit_status);
                    },
                    TaskStatus::Failed | TaskStatus::Stopped | TaskStatus::Closed => {
                        task.end_set_status(exit_status);
                        return Ok(());
                    }
                    _ => unreachable!()
                }
                drop(manager);
                
                // 等1s再获取结果
                thread::sleep(std::time::Duration::from_secs(1));
                let get_res = crate::tasks::task::task_get_result(id.clone()).await;
                match get_res {
                        Ok(result) => {
                            let mut manager = get_task_manager!()?.lock().await;
                            let task = manager.get_task_mut(&id).unwrap();
                            task.result = Some(result);
                            task.end_set_status(TaskStatus::ResultReceived);
                            drop(manager);
                        }
                        Err(e) => {
                            println!("getting result failed: {:?}", e);
                            let mut manager = get_task_manager!()?.lock().await;
                            let task = manager.get_task_mut(&id).unwrap();
                            task.end_set_status(TaskStatus::FailedToGetResult);
                        drop(manager);
                    }
                }

                thread::sleep(std::time::Duration::from_secs(5));
                let max_retries = 5;
                let interval_secs = 5;
                let mut retry = 0;
                let mut success = true;
                loop {
                    if let Ok(manager) = get_task_manager!()?.try_lock() {
                        let task = manager.get_task(&id).unwrap();
                        let logger = TASK_SUMMARY_LOGGER.lock().unwrap();
                        if let Err(e) = logger.log_task(task) {
                            println!("任务日志记录失败: {}", e);
                        }
                        let file_saver = TaskFileLogger::new();
                        file_saver.save_task_result(task)?;
                        drop(manager);
                        break;
                    }
                    else {
                        println!("任务管理器被锁……");
                        retry += 1;
                        if retry >= max_retries {
                            success = false;
                            println!("重复{}次拿不到锁，任务日志记录失败: {}", retry, id);
                            break;
                        }
                    }
                    thread::sleep(std::time::Duration::from_secs(interval_secs));
                }

                thread::sleep(std::time::Duration::from_secs(60));
                let mut retry = 0;
                loop {
                    if let Ok(mut manager) = get_task_manager!()?.try_lock() {
                        manager.remove_task(&id);
                        break;
                    }
                    else {
                        println!("任务管理器被锁……");
                        retry += 1;
                        if retry >= max_retries {
                            success = false;
                            println!("重复{}次拿不到锁，清除任务失败: {}", retry, id);
                            break;
                        }
                    }
                    thread::sleep(std::time::Duration::from_secs(interval_secs));
                }

                if success {
                    Ok(())
                }
                else {
                    Err(ServerError::TaskErrorStr("任务收尾失败"))
                }
            });
            res
        });
        Ok(())
    }
}

pub static TASK_MANAGER: OnceCell<Arc<tokio::sync::Mutex<TaskManager>>> = OnceCell::new();

pub fn init_task_manager() -> Result<(), ServerError> {
    let task_manager = TaskManager::new();
    TASK_MANAGER.set(Arc::new(tokio::sync::Mutex::new(task_manager))).map_err(|_| ServerError::SystemErrorStr("任务管理器初始化失败"))?;
    Ok(())
}
